"""
Service Monitoring Module
=========================
服务监控共享组件

提供服务级别的监控工具，包括：
- 业务步骤跟踪
- 依赖健康检查
- 缓存指标跟踪
- 数据新鲜度记录
"""

import logging
import time
from typing import Dict, Any, Optional, Callable
from contextlib import contextmanager
from datetime import datetime

logger = logging.getLogger(__name__)


class BusinessStepTracker:
    """
    业务步骤跟踪器
    
    用于跟踪业务操作的执行步骤，记录性能指标和成功/失败状态
    """
    
    def __init__(self, operation: str, step: str = "default"):
        """
        初始化业务步骤跟踪器
        
        Args:
            operation: 操作名称
            step: 步骤名称
        """
        self.operation = operation
        self.step = step
        self.start_time = None
        
    def __enter__(self):
        """进入上下文管理器"""
        self.start_time = time.time()
        logger.debug(f"Business step started: {self.operation}.{self.step}")
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        """退出上下文管理器"""
        duration = time.time() - self.start_time
        
        if exc_type is None:
            logger.debug(f"Business step completed: {self.operation}.{self.step} ({duration:.3f}s)")
            # 在实际实现中，这里应该调用监控系统记录指标
            # 例如: increment(f"business_operation_{self.operation}_success")
        else:
            logger.error(
                f"Business step failed: {self.operation}.{self.step} ({duration:.3f}s)",
                exc_info=(exc_type, exc_val, exc_tb)
            )
            # increment(f"business_operation_{self.operation}_error")


async def dependency_health_checker(service_name: str, check_func: Callable) -> bool:
    """
    依赖健康检查
    
    执行指定服务的健康检查函数，并记录结果
    
    Args:
        service_name: 服务名称
        check_func: 健康检查函数（可以是同步或异步）
        
    Returns:
        bool: 健康检查是否通过
    """
    try:
        # 执行健康检查
        if hasattr(check_func, '__call__'):
            result = await check_func() if hasattr(check_func, '__await__') else check_func()
        else:
            result = await check_func
            
        # 记录健康状态
        logger.info(f"Dependency health check for {service_name}: {'healthy' if result else 'unhealthy'}")
        # 在实际实现中，这里应该调用监控系统记录指标
        # set_gauge(f"dependency_{service_name}_healthy", 1 if result else 0)
        
        return bool(result)
        
    except Exception as e:
        logger.error(f"Health check failed for {service_name}: {e}")
        # set_gauge(f"dependency_{service_name}_healthy", 0)
        return False


def cache_metrics_tracker(cache_name: str, operation: str, hit: Optional[bool] = None):
    """
    缓存指标跟踪
    
    记录缓存操作的指标，包括命中率统计
    
    Args:
        cache_name: 缓存名称
        operation: 操作类型（get, set, delete等）
        hit: 是否命中（仅用于get操作）
    """
    logger.debug(f"Cache operation: {cache_name}.{operation} (hit={hit})")
    
    # 在实际实现中，这里应该调用监控系统记录指标
    # increment(f"cache_{cache_name}_{operation}_total")
    # if hit is not None:
    #     increment(f"cache_{cache_name}_{'hit' if hit else 'miss'}")


def record_data_freshness(data_type: str, timestamp: datetime, source: str = "default"):
    """
    记录数据新鲜度
    
    跟踪数据最后更新时间，用于监控数据新鲜度
    
    Args:
        data_type: 数据类型
        timestamp: 数据时间戳
        source: 数据源
    """
    now = datetime.now()
    age_seconds = (now - timestamp).total_seconds() if timestamp else 0
    
    logger.debug(f"Data freshness: {data_type} from {source} is {age_seconds:.1f}s old")
    
    # 在实际实现中，这里应该调用监控系统记录指标
    # set_gauge(f"data_freshness_{data_type}_{source}_seconds", age_seconds)


@contextmanager
def monitor_operation(operation: str, **metadata):
    """
    操作监控上下文管理器
    
    用于监控任意操作的执行时间和成功/失败状态
    
    Args:
        operation: 操作名称
        **metadata: 额外的元数据
    """
    start_time = time.time()
    logger.debug(f"Operation started: {operation} with metadata {metadata}")
    
    try:
        yield
        duration = time.time() - start_time
        logger.info(f"Operation completed: {operation} ({duration:.3f}s)")
        # increment(f"operation_{operation}_success")
        # histogram(f"operation_{operation}_duration_seconds", duration)
        
    except Exception as e:
        duration = time.time() - start_time
        logger.error(f"Operation failed: {operation} ({duration:.3f}s): {e}")
        # increment(f"operation_{operation}_error")
        raise


# 健康检查辅助类（用于更复杂的健康检查场景）
class HealthCheckRegistry:
    """健康检查注册表"""
    
    def __init__(self):
        self._checkers: Dict[str, Callable] = {}
        self._results: Dict[str, Dict[str, Any]] = {}
        
    def register(self, name: str, check_func: Callable):
        """注册健康检查函数"""
        self._checkers[name] = check_func
        logger.info(f"Registered health checker: {name}")
        
    def unregister(self, name: str):
        """注销健康检查函数"""
        if name in self._checkers:
            del self._checkers[name]
            logger.info(f"Unregistered health checker: {name}")
            
    async def check_all(self) -> Dict[str, Dict[str, Any]]:
        """执行所有健康检查"""
        results = {}
        
        for name, checker in self._checkers.items():
            try:
                start_time = time.time()
                is_healthy = await dependency_health_checker(name, checker)
                duration = time.time() - start_time
                
                results[name] = {
                    'healthy': is_healthy,
                    'duration': duration,
                    'timestamp': datetime.now().isoformat()
                }
                
            except Exception as e:
                results[name] = {
                    'healthy': False,
                    'error': str(e),
                    'timestamp': datetime.now().isoformat()
                }
                
        self._results = results
        return results
        
    def get_results(self) -> Dict[str, Dict[str, Any]]:
        """获取最近的健康检查结果"""
        return self._results


# 全局健康检查注册表实例
_global_health_registry = HealthCheckRegistry()


def get_health_registry() -> HealthCheckRegistry:
    """获取全局健康检查注册表"""
    return _global_health_registry

